home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games: Greatest Hits 1996 / Amiga Games: Greatest Hits 1996.iso / userbox / publicdomain / superplay-lib_dev / programmers / example_spobjects / spo / sp_playsubs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-27  |  8.9 KB  |  299 lines

  1.  
  2.  /* SP_PlaySubs.c
  3.     - Functions for Playing SPO Files -
  4.     (c) 1994-96 by Andreas R. Kleinert
  5.     Last changes : 27.05.1996
  6.  */
  7.  
  8.  
  9. #include "spobject.h"
  10.  
  11. #include <exec/devices.h>
  12. #include <devices/audio.h>
  13.  
  14. ULONG __saveds __asm SPO_Read( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
  15. ULONG __saveds __asm SPO_StartReplay( register __a1 struct SPObjectHandle *SPObjectHandle);
  16. ULONG __saveds __asm SPO_ContinueReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
  17. ULONG __saveds __asm SPO_FastForward( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
  18. ULONG __saveds __asm SPO_FastBackward( register __a1 struct SPObjectHandle *SPObjectHandle_a1);
  19.  
  20.  
  21. ULONG __saveds __asm SPO_Read( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
  22. {
  23.  struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
  24.  
  25.  ULONG retval = SPERR_NO_ERROR;
  26.  struct TagItem __aligned xpk_pars [5];
  27.  UBYTE          *Buf           = N;
  28.  ULONG           BufSize       = N, xpk_errorcode;
  29.  char filename [256], filename_spo [256];
  30.  
  31.  if(!SPObjectHandle) return(SPERR_NO_HANDLE);
  32.  
  33.  SPObjectHandle->ah_SPOHeader = AllocVec(sizeof(struct SPOHeader), (MEMF_CLEAR|MEMF_PUBLIC));
  34.  if(!SPObjectHandle->ah_SPOHeader) return(SPERR_NO_MEMORY);
  35.  
  36.  SPObjectHandle->ah_ramhandle = AIM_GetMemList();
  37.  if(!SPObjectHandle->ah_ramhandle) return(SPERR_NO_MEMORY);
  38.  
  39.  if(strlen(SPObjectHandle->ah_ReadName) > 4)
  40.   {
  41.    if(!stricmp(&SPObjectHandle->ah_ReadName[strlen(SPObjectHandle->ah_ReadName)-4], ".spo"))
  42.     {
  43.      strcpy(filename_spo, SPObjectHandle->ah_ReadName);
  44.      strcpy(filename,     SPObjectHandle->ah_ReadName);
  45.      filename[strlen(filename)-4] = (char) 0;
  46.     }else
  47.     {
  48.      strcpy(filename,     SPObjectHandle->ah_ReadName);
  49.      strcpy(filename_spo, SPObjectHandle->ah_ReadName);
  50.      strcat(filename_spo, ".spo");
  51.     }
  52.   }else
  53.   {
  54.    strcpy(filename_spo, SPObjectHandle->ah_ReadName);
  55.    strcat(filename_spo, ".spo");
  56.    strcpy(filename,     SPObjectHandle->ah_ReadName);
  57.   }
  58.  
  59.  SPObjectHandle->ah_filehandle_source = Open(filename_spo, MODE_OLDFILE);
  60.  if(!SPObjectHandle->ah_filehandle_source) return(SPERR_NO_FILE);
  61.  
  62.  Read(SPObjectHandle->ah_filehandle_source, SPObjectHandle->ah_SPOHeader, SPOHEADER_SIZE);
  63.  
  64.  if(SPObjectHandle->ah_SPOHeader->spo_SampleBits > 8) return(SPERR_UNKNOWN_PARAMETERS);
  65.     /* yet only 8-Bit Sample Data */
  66.  
  67.  /* Read XPK Data */
  68.  
  69.  xpk_pars[0].ti_Tag  = XPK_GetOutBuf;
  70.  xpk_pars[0].ti_Data = (ULONG) &Buf;
  71.  
  72.  xpk_pars[1].ti_Tag  = XPK_GetOutBufLen;
  73.  xpk_pars[1].ti_Data = (ULONG) &BufSize;
  74.  
  75.  xpk_pars[2].ti_Tag  = XPK_InName;
  76.  xpk_pars[2].ti_Data = (ULONG) filename;
  77.  
  78.  xpk_pars[3].ti_Tag  = XPK_PassThru;
  79.  xpk_pars[3].ti_Data = (ULONG) TRUE;
  80.  
  81.  xpk_pars[4].ti_Tag  = TAG_DONE;
  82.  xpk_pars[4].ti_Data = N;
  83.  
  84.  xpk_errorcode = XpkUnpack(&xpk_pars[0]);
  85.  if(!xpk_errorcode)
  86.   {
  87.    SPObjectHandle->ah_XpkBuffer = AllocVec(BufSize, (MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP));
  88.    if(SPObjectHandle->ah_XpkBuffer)
  89.     {
  90.      SPObjectHandle->ah_XpkBufferSize = BufSize;
  91.  
  92.      CopyMem(Buf, SPObjectHandle->ah_XpkBuffer, SPObjectHandle->ah_XpkBufferSize);
  93.      FreeMem(Buf, BufSize);
  94.  
  95.      SPObjectHandle->ah_SampleList = SPLI_GetSampleList();
  96.      if(SPObjectHandle->ah_SampleList) SPLI_AddSample(SPObjectHandle->ah_SampleList, SPObjectHandle->ah_XpkBuffer, SPObjectHandle->ah_XpkBufferSize, 8, SPObjectHandle->ah_SPOHeader->spo_Frequency, 64);
  97.  
  98.     }else retval = SPERR_NO_MEMORY;
  99.   }else retval = SPERR_DECODE_ERROR;
  100.  
  101.  return(retval);
  102. }
  103.  
  104. void __stdargs SPLI_PlayTask(void);
  105. void __stdargs SPLI_EO_PlayTask(void);
  106.  
  107. ULONG __saveds __asm SPO_StartReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
  108. {
  109.  struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
  110.  ULONG retval = SPERR_NO_ERROR;
  111.  
  112.  if(!SPObjectHandle) return(SPERR_NO_HANDLE);
  113.  
  114.  SPObjectHandle->ah_PlayTask = AllocVec(sizeof(struct Task), (MEMF_CLEAR|MEMF_PUBLIC));
  115.  if(SPObjectHandle->ah_PlayTask)
  116.   {
  117.    SPObjectHandle->ah_TaskStopNext = FALSE;
  118.  
  119.    SPObjectHandle->ah_PlayTask->tc_Node.ln_Type = NT_TASK;
  120.    SPObjectHandle->ah_PlayTask->tc_Node.ln_Name = "SPO.spobject";
  121.  
  122.    SPObjectHandle->ah_PlayTask->tc_SPLower = AllocVec(4096, (MEMF_CLEAR|MEMF_PUBLIC));
  123.    if(SPObjectHandle->ah_PlayTask->tc_SPLower)
  124.     {
  125.      SPObjectHandle->ah_PlayTask->tc_SPUpper = (APTR) ((ULONG)SPObjectHandle->ah_PlayTask->tc_SPLower + (ULONG)4096);
  126.      SPObjectHandle->ah_PlayTask->tc_SPReg   = SPObjectHandle->ah_PlayTask->tc_SPUpper;
  127.  
  128.      SPObjectHandle->ah_PlayTask->tc_UserData = SPObjectHandle;
  129.  
  130.      AddTask(SPObjectHandle->ah_PlayTask, SPLI_PlayTask, N);
  131.  
  132.      /* Get possible failure error code */
  133.  
  134.      Delay(100);
  135.      if(!SPObjectHandle->ah_TaskRunning) retval = SPObjectHandle->ah_TaskRetVal;
  136.  
  137.     }else retval = SPERR_NO_MEMORY;
  138.  
  139.   }else retval = SPERR_NO_MEMORY;
  140.  
  141.  return(retval);
  142. }
  143.  
  144. /* *************************************************** */
  145. /* *                             * */
  146. /* * Functions for a separate Player-Task            * */
  147. /* *                             * */
  148. /* *************************************************** */
  149.  
  150. void __stdargs SPLI_PlayTask(void)
  151. {
  152.  ULONG opres = N, sound_len, sound_play, sound_long, sound_rest;
  153.  UBYTE channel, *sound_buf;
  154.  struct IOAudio *audioreq  = N;
  155.  struct MsgPort *audioport = N;
  156.  struct SPObjectHandle *SPObjectHandle = N;
  157.  APTR msg;
  158.  struct Task *task = N;
  159.  
  160.  task = FindTask(N);
  161.  
  162.  SetTaskPri(task, 1);
  163.  SPObjectHandle = task->tc_UserData;
  164.  
  165.  if(!SPObjectHandle)
  166.   {
  167.    SPObjectHandle->ah_TaskRetVal = SPERR_NO_HANDLE;
  168.    return;
  169.   }
  170.  
  171.  SPObjectHandle->ah_TaskRunning = TRUE;
  172.  
  173.  audioport = (struct MsgPort  *) CreatePort("SPO.spobject", N);
  174.  if(audioport)
  175.   {
  176.    audioreq  = (struct IOAudio  *) CreateExtIO(audioport, sizeof(struct IOAudio));
  177.    if(audioreq)
  178.     {
  179.      channel = SPObjectHandle->ah_SPOHeader->spo_Channels;
  180.  
  181.      audioreq->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
  182.      audioreq->ioa_Data                              = (APTR) &channel;
  183.      audioreq->ioa_Length                            = 1;
  184.      audioreq->ioa_AllocKey                          = 0;
  185.  
  186.      opres = OpenDevice("audio.device", 0, (struct IORequest *) audioreq, N);
  187.      if(!opres)
  188.       {
  189.        while(!SPObjectHandle->ah_TaskStopNext)
  190.         {
  191.          sound_play = TRUE;
  192.          sound_buf  = SPObjectHandle->ah_XpkBuffer;
  193.          sound_rest = SPObjectHandle->ah_SPOHeader->spo_SampleLength;
  194.  
  195.          while(sound_play)
  196.           {
  197.            if(sound_rest <= 0xFFFF)
  198.             {
  199.              sound_len  = sound_rest;
  200.              sound_long = FALSE;
  201.              sound_play = FALSE;
  202.             }else
  203.             {
  204.              sound_len  = 0xFFFF;
  205.              sound_long = TRUE;
  206.  
  207.              sound_rest -= sound_len;
  208.             }
  209.  
  210.            audioreq->ioa_Request.io_Command = CMD_WRITE;
  211.            audioreq->ioa_Request.io_Flags   = ADIOF_PERVOL;
  212.            audioreq->ioa_Data               = sound_buf;
  213.            audioreq->ioa_Cycles             = 1;
  214.            audioreq->ioa_Length             = sound_len;
  215.            audioreq->ioa_Period             = 3579546 / SPObjectHandle->ah_SPOHeader->spo_Frequency;
  216.            audioreq->ioa_Volume             = SPObjectHandle->ah_SPOHeader->spo_Volume;
  217.  
  218.            BeginIO((struct IORequest *) audioreq);
  219.            WaitIO((struct IORequest *) audioreq);
  220.  
  221.            sound_buf += sound_len;
  222.           }
  223.         }
  224.  
  225.        audioreq->ioa_Request.io_Command = ADCMD_FINISH;
  226.        audioreq->ioa_Request.io_Flags   = 0;
  227.        audioreq->ioa_Data               = 0;
  228.        audioreq->ioa_Cycles             = 0;
  229.        audioreq->ioa_Length             = 0;
  230.        audioreq->ioa_Period             = 0;
  231.        audioreq->ioa_Volume             = 0;
  232.  
  233.        DoIO((struct IORequest *) audioreq);
  234.  
  235.        CloseDevice((struct IORequest *) audioreq);
  236.  
  237.       }else SPObjectHandle->ah_TaskRetVal = SPERR_NO_CHANNELS;
  238.  
  239.      DeleteExtIO((struct IORequest *) audioreq);
  240.  
  241.     }else SPObjectHandle->ah_TaskRetVal = SPERR_NO_MEMORY;
  242.  
  243.    while( msg = (APTR)GetMsg(audioport) ) ReplyMsg((APTR)msg);
  244.  
  245.    DeletePort(audioport);
  246.  
  247.   }else SPObjectHandle->ah_TaskRetVal = SPERR_NO_MEMORY;
  248.  
  249.  Forbid();
  250.  
  251.  SPObjectHandle->ah_TaskRunning  = FALSE;
  252.  SPObjectHandle->ah_TaskStopNext = FALSE;
  253.  
  254.  Permit();
  255.  
  256.  Wait(1<<31); /* this signal never comes ... */
  257. }
  258.  
  259. void __stdargs SPLI_EO_PlayTask(void)
  260. {
  261.  /* dummy-func */
  262. }
  263.  
  264. ULONG __saveds __asm SPO_ContinueReplay( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
  265. {
  266.  struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
  267.  ULONG retval = SPERR_NO_ERROR;
  268.  
  269.  if(!SPObjectHandle) return(SPERR_NO_HANDLE);
  270.  
  271.  retval = SPERR_ACTION_NOT_SUPPORTED;
  272.  
  273.  return(retval);
  274. }
  275.  
  276. ULONG __saveds __asm SPO_FastForward( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
  277. {
  278.  struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
  279.  ULONG retval = SPERR_NO_ERROR;
  280.  
  281.  if(!SPObjectHandle) return(SPERR_NO_HANDLE);
  282.  
  283.  retval = SPERR_ACTION_NOT_SUPPORTED;
  284.  
  285.  return(retval);
  286. }
  287.  
  288. ULONG __saveds __asm SPO_FastBackward( register __a1 struct SPObjectHandle *SPObjectHandle_a1)
  289. {
  290.  struct SPObjectHandle *SPObjectHandle = SPObjectHandle_a1;
  291.  ULONG retval = SPERR_NO_ERROR;
  292.  
  293.  if(!SPObjectHandle) return(SPERR_NO_HANDLE);
  294.  
  295.  retval = SPERR_ACTION_NOT_SUPPORTED;
  296.  
  297.  return(retval);
  298. }
  299.